package com.zynn.service.module.es.service;

import com.google.common.collect.Lists;
import com.zynn.common.pojo.dto.school.SchoolInviteRecordDTO;
import com.zynn.service.module.es.dao.UsersMapper;
import com.zynn.service.module.es.entity.SchoolRecommentFriend;
import com.zynn.service.module.es.entity.SchoolUserFriend;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;

/**
 * @author 刘猛
 * @description 初始化高校每个用户的一度好友
 * @create 2018-09-14
 **/
@Slf4j
@Service
public class InitVersionSchoolUserFriendsService {

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private RestHighLevelClient client;

//    @Autowired
//    SchoolInviteRecordFeignService schoolInviteRecordFeignService;

    /**
     * 权重分数100分
     */
    private static final int SCORE100 = 100;
    /**
     * 权重分数80分
     */
    private static final int SCORE80 = 80;
    /**
     * 权重分数70分
     */
    private static final int SCORE70 = 70;

    /**
     * 权重分数60分
     */
    private static final int SCORE60 = 60;

    /**
     * 权重分数60分
     */
    private static final int SCORE50 = 50;

    /**
     * 权重分数30分
     */
    private static final int SCORE30 = 30;

    /**
     *权重分数20
     */
    private static final int SCORE20 = 20;

    /*-----有市场行为------*/
    /**
     * 1、成功邀请20人以上;
     * 2、发出邀请8次以上;
     * 3、发出邀请3天及以上
     */
    private static  final int[] market_behavior_invite_count_of_score_100= {20,9999};
    private static  final int[] market_behavior_send_invite_count_of_score_100={8,9999};
    private static  final int[] market_behavior_send_invite_days_of_score_100={3,9999};

    /**
     * 1、成功邀请10-20人;
     * 2、发出邀请5-8次;
     * 3、发出邀请2天；
     */
    private static  final int[] market_behavior_invite_count_of_score_80= {10,20};
    private static  final int[] market_behavior_send_invite_count_of_score_80={5,8};
    private static  final int[] market_behavior_send_invite_days_of_score_80={2,2};

    /**
     * 1、成功邀请5-10人;
     * 2、发出邀请3-5次;
     */
    private static  final int[] market_behavior_invite_count_of_score_70= {5,10};
    private static  final int[] market_behavior_send_invite_count_of_score_70={3,5};

    /**
     * 1、成功邀请2-5人;
     * 2、发出邀请2次;
     */
    private static  final int[] market_behavior_invite_count_of_score_60= {2,5};
    private static  final int[] market_behavior_send_invite_count_of_score_60={1,3};

    /**
     * 1、成功邀请1人;
     * 2、发出邀请1次;
     */
    private static  final int[] market_behavior_invite_count_of_score_50= {1,2};
    private static  final int[] market_behavior_send_invite_count_of_score_50={1,2};

    /**
     * 1、助力1次
     */
    private static  final int[] market_behavior_assist_count_of_score_30= {1,2};

    /*--------无市场行为-------*/
    /**
     * 1、通过邀请进入5次以上；
     */
    private static  final int[] no_market_behavior_invite_join_count_of_score_100= {5,9999};

    /**
     * 1、通过邀请进入4-5次；
     */
    private static  final int[] no_market_behavior_invite_join_count_of_score_70= {4,5};

    /**
     * 1、通过邀请进入3次
     */
    private static  final int[] no_market_behavior_invite_join_count_of_score_50= {3,4};

    /**
     * 1、通过邀请进入2次；
     */
    private static  final int[] no_market_behavior_invite_join_count_of_score_30= {2,3};

    /**
     * 1、通过邀请进入1次；
     */
    private static  final int[] no_market_behavior_invite_join_count_of_score_20= {1,2};


    /**
     * 计算一个用户的一，二，三度好友
     * @param userId
     */
    public void initVersionSchoolUserFriendsWithWeight(Long userId,Long beLikedUserId) {
        /**
         * 旧版高校推荐（弃用）
         */
       /*List<Map<String,Object>> recommendList =  schoolInviteRecordFeignService.queryUserRecommendWithWeight(userId,beLikedUserId).getData();
       if(!CollectionUtils.isEmpty(recommendList)){
          List<String> friendWithWeightVersionSchool = recommendList.stream().map((e) -> e.get("score") +"|"+ e.get("userId")).collect(Collectors.toList());
          this.syncDegOneFriendsOfVersionSchool(userId,null,friendWithWeightVersionSchool);
       }*/

        /**
         * 将该用户一二三度好友全部计算出来
         */
//        List<Map<String,Object>> recommendListDegAll = schoolInviteRecordFeignService.queryUserRecommendWithWeightDegAll(userId).getData();
//        if(!CollectionUtils.isEmpty(recommendListDegAll)){
//            List<String> friendWithWeightVersionSchool = recommendListDegAll.stream().map((e) -> e.get("score") +"|"+ e.get("userId") + "|" + e.get("degWeight")).collect(Collectors.toList());
//            this.syncDegOneFriendsOfVersionSchool(userId,null,friendWithWeightVersionSchool);
//        }

    }

    /**
     * 将推荐好友信息同步到es
     * @param userId
     * @param userIdList
     * @param friendWithWeightVersionSchool
     */
    private void syncDegOneFriendsOfVersionSchool(Long userId, List<Long> userIdList, List<String> friendWithWeightVersionSchool) {
        if(RecommandUtil.existsIndex(userId,client)){
            this.updateSchoolIndex(userId,friendWithWeightVersionSchool);
        }else{
            this.createSchoolIndex(userId,userIdList,friendWithWeightVersionSchool);
        }
    }


    /**
     * 校园版推荐索引（更新）
     * @param userId
     * @param userIdList
     * @param friendWithWeightVersionSchool
     */
    private void updateSchoolIndex(Long userId, List<String> friendWithWeightVersionSchool){
        Map<String, Object> jsonMap = new HashMap<>(20);
        jsonMap.put("school_deg_one_friend", friendWithWeightVersionSchool);

        //Map会自动转换为JSON格式的文档源
        UpdateRequest indexRequest = new UpdateRequest("user_friend_index", "_doc", userId.toString())
                .doc(jsonMap);
        UpdateResponse indexResponse = null;
        try {
            indexResponse = client.update(indexRequest);
            log.info(indexResponse.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 校园版推荐索引（创建）
     * @param userId
     * @param userIdList
     * @param friendWithWeightVersionSchool
     */
    private void createSchoolIndex(Long userId, List<Long> userIdList, List<String> friendWithWeightVersionSchool){
        Map<String, Object> jsonMap = new HashMap<>(20);
        jsonMap.put("user_id", userId);
        jsonMap.put("deg_one_frient", userIdList);
        jsonMap.put("school_deg_one_friend", friendWithWeightVersionSchool);

        //Map会自动转换为JSON格式的文档源
        IndexRequest indexRequest = new IndexRequest("user_friend_index", "_doc", userId.toString())
                .source(jsonMap);
        IndexResponse indexResponse = null;
        try {
            indexResponse = client.index(indexRequest);
            log.info(indexResponse.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 快速去重
     * @param list
     * @return
     */
    private List<SchoolInviteRecordDTO> distinctSchoolInviteRecordList(List<SchoolInviteRecordDTO> list){
        List<SchoolInviteRecordDTO> rsList = Lists.newLinkedList();
        Set<String> set = new HashSet<>();
        if(CollectionUtils.isEmpty(list)){
            return rsList;
        }
        list.forEach((item) -> {
                if(set.add(item.getInviteUserId()+""+item.getBeInvitedUserId())){
                    rsList.add(item);
                }
            }
        );
        return rsList;
    }

    /**
     * 推荐好友赋值权重
     * @param friend
     * @param recommendfriends
     * @param score
     */
    private void handleRecommendUsersWithWeight(SchoolUserFriend friend, List<?> recommendfriends, int score){
        if(CollectionUtils.isEmpty(recommendfriends)){return;}
        recommendfriends.forEach((item) ->{
            if( item instanceof SchoolInviteRecordDTO){
                friend.getRecommentFriends().add(new SchoolRecommentFriend(((SchoolInviteRecordDTO) item).getInviteUserId(),score));
            }
        });
    }

}
